import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import javax.media.nativewindow.util.*;
import javax.media.opengl.*;

import com.jogamp.newt.*;
import com.jogamp.newt.event.KeyAdapter;
import com.jogamp.newt.event.KeyEvent;
import com.jogamp.newt.event.WindowAdapter;
import com.jogamp.newt.event.WindowEvent;
import com.jogamp.newt.opengl.*;

import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2; // have to add Tests
import com.jogamp.opengl.test.junit.util.QuitAdapter;
import com.jogamp.opengl.util.Animator;

// 2012.02.08 JBS
// TODO: play with JOGL!

class Test1
{
	GLProfile glp; // stores GL profile
	static int screenIdx = 0; // 
	static boolean opaque = true;
	GLCapabilities caps;

	static PointImmutable wpos;
	static DimensionImmutable wsize;

    static boolean undecorated = false;
    static boolean alwaysOnTop = false;
    static boolean fullscreen = false;
    static boolean pmvUseBackingArray = true;
    static boolean vsync = true;
    static boolean waitForKey = false;
    static boolean mouseVisible = true;
    static boolean mouseConfined = false;
    static boolean showFPS = false;

	public Test1( ) throws InterruptedException
	{
		glp = GLProfile.getGL2ES2( ); 		// stores gl profile info
		caps = new GLCapabilities( glp ); 	// stores gl capabilities and contains specs
		caps.setBackgroundOpaque( opaque ); // set caps background opacity

		Display dpy = NewtFactory.createDisplay( null );			// makes a NEWT display
		Screen screen = NewtFactory.createScreen( dpy, screenIdx );	// inits screen with display
		final GLWindow glw = GLWindow.create( screen, caps );		// uses screen with caps

		wsize = new Dimension( screen.getHeight( ), screen.getWidth( ) );
		wpos  = new Point( (int)( 0.5*screen.getHeight( ) ), (int)( 0.5*screen.getWidth( ) ) );
		
		glw.setTitle( "Hello JOGL!" );
		glw.setSize( wsize.getHeight( ), wsize.getWidth( ) );
		glw.setPosition( wpos.getX( ), wpos.getY( ) );

        glw.setUndecorated( undecorated );
        glw.setAlwaysOnTop( alwaysOnTop );
        glw.setFullscreen( fullscreen );
        glw.setPointerVisible( mouseVisible );
        glw.confinePointer( mouseConfined );
        
        final GearsES2 demo = new GearsES2( vsync ? 1 : 0 );
        demo.setPMVUseBackingArray( pmvUseBackingArray );
        
        glw.addGLEventListener( demo );
        
        if( waitForKey )
        {
        	glw.addGLEventListener(
        		new GLEventListener( )
        		{
        			public void init( GLAutoDrawable drawable ) { }
        			public void dispose( GLAutoDrawable drawable ) { }
        			public void display( GLAutoDrawable drawable )
        			{
        				GLAnimatorControl actrl = drawable.getAnimator( );
        				if( waitForKey && actrl.getTotalFPSFrames( ) == 60*3 )
        				{
        					BufferedReader stdin = 
        						new BufferedReader( new InputStreamReader( System.in ) );
        					System.err.println( "Press enter to continue" );
        					
        					try
        					{
        						System.err.println( stdin.readLine( ) );
        					} catch( IOException e ) { }
                        
        					actrl.resetFPSCounter( );
        					waitForKey = false;
        				}
        			}
                
        			public void reshape( GLAutoDrawable drawable, int x, int y,
        				int width, int height ) { }
        		}
        	);
        }
        
        Animator a = new Animator( glw );
        QuitAdapter qa = new QuitAdapter( );
        
        glw.addKeyListener( qa );
        glw.addWindowListener( qa );
        
        glw.addWindowListener( new WindowAdapter( ) 
        	{
            	public void windowResized( WindowEvent e ) { }
            	public void windowMoved( WindowEvent e ) { }      
        	}
        );

        glw.addKeyListener( new KeyAdapter( ) 
	        {
	            public void keyTyped( KeyEvent e )
	            {
	                if( e.getKeyChar( ) == 'f' )
	                {
	                    new Thread( ) 
	                    {
	                        public void run( )
	                        {
	                            glw.setFullscreen( !glw.isFullscreen( ) );
	                        } 
	                    }.start( );
	                } 
	                else if( e.getKeyChar( ) == 'a' )
	                {
	                    new Thread( )
	                    {
	                        public void run( )
	                        {
	                            glw.setAlwaysOnTop( !glw.isAlwaysOnTop( ) );
	                        }
	                    }.start( );
	                } else if( e.getKeyChar( ) == 'd' )
	                {
	                    new Thread( )
	                    {
	                        public void run( )
	                        {
	                            glw.setUndecorated( !glw.isUndecorated( ) );
	                        }
	                    }.start( );
	                } else if( e.getKeyChar( ) == 's' )
	                {
	                    new Thread( )
	                    {
	                        public void run( )
	                        {
	                            glw.setPosition( 100, 100 );
	                        }
	                    }.start( );
	                } else if( e.getKeyChar( ) == 'i' )
	                {
	                    new Thread( )
	                    {
	                        public void run( )
	                        {
	                            glw.setPointerVisible( !glw.isPointerVisible( ) );
	                        }
	                    }.start( );
	                } else if( e.getKeyChar( ) == 'j' )
	                {
	                    new Thread( )
	                    {
	                        public void run( )
	                        {
	                            glw.confinePointer( !glw.isPointerConfined( ) );
	
	                            if( !glw.isPointerConfined( ) )
	                            {
	                                demo.setConfinedFixedCenter( false );
	                            }
	                        }
	                    }.start( );
	                } else if( e.getKeyChar( ) == 'J' )
	                {
	                    new Thread( )
	                    {
	                        public void run( )
	                        {
	                            glw.confinePointer( !glw.isPointerConfined( ) );
	                            demo.setConfinedFixedCenter( glw.isPointerConfined( ) );
	                        }
	                    }.start( );
	                } else if( e.getKeyChar( ) == 'w' )
	                {
	                    new Thread( )
	                    {
	                        public void run( )
	                        {
	                            glw.warpPointer( glw.getWidth( )/2, glw.getHeight( )/2 );
	                            System.err.println("[set mouse pos post]");
	                        }
	                    }.start( );
	                }
	            }
	        }
        );

        a.setUpdateFPSFrames( 60, showFPS ? System.err : null );
        a.start( );
        
        glw.setVisible( true );
        
        while( !qa.shouldQuit( ) && a.isAnimating( ) )
        {
            Thread.sleep(100);
        }
        
        a.stop( );
        glw.destroy( );
	}

	public static void main( String[] args ) throws IOException
	{
        if( waitForKey )
        {
            BufferedReader stdin = new BufferedReader( new InputStreamReader( System.in ) );
            System.err.println( "Press enter to continue" );
            
            try
            {
                System.err.println( stdin.readLine( ) );
            } catch( IOException e ) { }
        }

        try
        {
        	Test1 t1 = new Test1( );
        } catch( InterruptedException ie )
        {
        	
        }
	}
}
